package com.skyline.wo.controller;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.imagine.core.ResultState;
import net.imagine.core.engine.ImageEngine;
import net.imagine.provider.fastdfs.FastDFSFileOperator;
import net.imagine.provider.skyline.ImageCropResult;
import net.imagine.provider.skyline.ImageCutter;
import net.imagine.provider.skyline.ImageResizeResult;
import net.imagine.provider.skyline.LocalImageResizeTask;
import net.imagine.provider.skyline.MultipartImageResizeTask;
import net.imagine.provider.skyline.SkylineImageCropTask;
import net.imagine.provider.skyline.SkylineImageResizeTask;
import net.imagine.provider.skyline.SkylineImagineUtils;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.skyline.base.controller.BaseController;
import com.skyline.base.exception.NoResourceException;
import com.skyline.base.exception.NoVisitPermissionException;
import com.skyline.base.exception.NotLoginException;
import com.skyline.base.exception.OperateFailedException;
import com.skyline.common.bean.Page;
import com.skyline.common.util.AuthorityUtil;
import com.skyline.common.util.CommonUtils;
import com.skyline.common.util.Constant;
import com.skyline.common.util.ViewPaths;
import com.skyline.common.util.WebHelper;
import com.skyline.common.validation.Errors;
import com.skyline.common.validation.ValidationUtils;
import com.skyline.user.model.User;
import com.skyline.user.service.PersonalInfoService;
import com.skyline.wo.model.Album;
import com.skyline.wo.model.Photo;
import com.skyline.wo.service.AlbumService;

/**
 * 相册模块的Controller
 * 
 * @author wuqh
 * */
@Controller
@RequestMapping(value = "/album")
public class AlbumController extends BaseController {
	private static final Log LOGGER = LogFactory.getLog(AlbumController.class);
	private static final String URL_PREFIX = "/album";
	@Autowired
	private AlbumService albumService;
	@Autowired
	private PersonalInfoService personalInfoService;

	@Autowired
	private ImageEngine imagine;
	private @Value("${imagine.localStorePath}")
	String localStorePath;
	private @Value("${imagine.baseSize1},${imagine.baseSize2}")
	int[] baseSizes;
	private @Value("${album.cover.defaultCover}")
	String cover;
	private @Value("${album.cover.defaultExt}")
	String ext;
	@Autowired
	private ImageCutter crop;
	private @Value("${imagine.protraitSize}")
	int portraitSize;
	@Autowired(required = false)
	private FastDFSFileOperator fileOperator;

	private @Value("${album.uploadphoto.filesize}")
	long maxSizePerFile;
	private @Value("${album.listalbum.pagesize}")
	int listAlbumPageSize;
	private @Value("${album.listphoto.pagesize}")
	int listPhotoPageSize;

	/**
	 * 相册首页，显示ownerId指定用户的所有相册（包括头像相册）
	 * 
	 * 转到相册列表页面
	 * 
	 * @param ownerId
	 *            用户ID
	 * @param page
	 * */
	@RequestMapping(value = "/list/{ownerId}", method = RequestMethod.GET)
	public ModelAndView listAlbum(@PathVariable("ownerId") Long ownerId, Page page) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		long viewerId = 0;// 默认访问者的ID为0
		if (user != null) {
			viewerId = user.getId();
		}
		int authority = AuthorityUtil.getAuthority(null, viewerId);
		page.setSize(listAlbumPageSize);
		List<Album> albums = albumService.listAlbumDetailsOfUserWithPortrait(ownerId, viewerId,
				authority, page);
		ModelAndView mav = new ModelAndView(ViewPaths.ALBUM_LISTALBUM);
		// 设置request
		mav.addObject("page", page);
		mav.addObject("albums", albums);
		if (!CollectionUtils.isEmpty(albums)) {
			mav.addObject("ownerId", albums.get(0).getOwnerId());
			mav.addObject("ownerName", albums.get(0).getOwnerNickname());
		} else {
			LOGGER.warn("数据异常，取到ID为:" + ownerId + "的相册列表为空，但是实际上至少会返回头像相册");
		}
		return mav;
	}

	/**
	 * 照片列表页面，显示albumId指定相册
	 * 
	 * 转到相册列表页面
	 * 
	 * @param albumId
	 *            用户ID
	 * @param page
	 * */
	@RequestMapping(value = "/view/{albumId}", method = RequestMethod.GET)
	public ModelAndView viewAlbum(@PathVariable("albumId") Long albumId, Page page) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		long viewerId = 0;
		boolean addVisitCount = false;
		if (user != null) {
			viewerId = user.getId();
			// FIXME :判断是否需要增加访问量
		}
		int authority = AuthorityUtil.getAuthority(null, viewerId);

		page.setSize(listPhotoPageSize);

		Album album = albumService.getAlbumById(albumId);
		// 判断权限
		if (album != null) {
			int albumAuth = album.getAuthority();
			if (authority < albumAuth) {
				throw new NoVisitPermissionException("ID为:" + viewerId + "的用户没有访问ID为:"
						+ album.getId() + "相册的权限");
			}
		} else {
			throw new NoVisitPermissionException("ID:" + viewerId + "没有访问相册的权限");
		}
		List<Photo> photos = albumService.listPhotosOfAlbum(albumId, viewerId, authority, page,
				addVisitCount);

		ModelAndView mav = new ModelAndView(ViewPaths.ALBUM_VIEWALBUM);
		mav.addObject("ownerId", album.getOwnerId());
		mav.addObject("ownerName", album.getOwnerNickname());
		mav.addObject("albumId", album.getId());
		mav.addObject("page", page);
		mav.addObject("photos", photos);
		mav.addObject("album", album);

		return mav;
	}

	/**
	 * 图片展示页面，显示photoId指定图片
	 * 
	 * 转到相册列表页面
	 * 
	 * @param albumId
	 *            用户ID
	 * */
	@RequestMapping(value = "/photo/{photoId}", method = RequestMethod.GET)
	public ModelAndView viewPhoto(@PathVariable("photoId") Long photoId) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		long viewerId = 0;
		boolean addVisitCount = false;
		if (user != null) {
			viewerId = user.getId();
			// 此处不增加浏览数，统一在通过ajax方式获取图片信息是处理
		}
		int authority = AuthorityUtil.getAuthority(null, viewerId);

		Photo photo = albumService.getPhotoDetailById(photoId, viewerId, addVisitCount);
		// 判断权限
		if (photo != null) {
			int albumAuth = photo.getAuthority();
			if (authority < albumAuth) {
				throw new NoVisitPermissionException("ID为:" + viewerId + "的用户没有访问ID为:"
						+ photo.getId() + "图片的权限");
			}
		} else {
			throw new NoResourceException("ID为:" + photoId + "的图片不存在");
		}
		List<Photo> photos = albumService.listPhotoFilesOfAlbum(photo.getAlbumId(), authority);

		ModelAndView mav = new ModelAndView(ViewPaths.ALBUM_VIEWPHOTO);
		mav.addObject("photo", photo);
		mav.addObject("photos", photos);

		return mav;
	}

	/**
	 * 删除相册
	 * 
	 * @param albumId
	 *            相册Id
	 * @param page
	 * */
	@RequestMapping(value = "/delalbum/{albumId}", method = { RequestMethod.GET, RequestMethod.POST })
	public ModelAndView deleteAlbum(@PathVariable("albumId") long albumId, Page page) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		long userId = 0;
		if (user != null) {
			userId = user.getId();
		}

		albumService.deleteAlbum(albumId, userId);
		String url = buildRecirectPath(URL_PREFIX + "/list/" + userId);
		url = url + "?curpage=" + page.getCurpage();

		ModelAndView mav = new ModelAndView(new RedirectView(url));
		return mav;
	}

	/**
	 * 打开修改相册页面
	 * 
	 * @param albumId
	 *            相册Id
	 * @param page
	 * */
	@RequestMapping(value = "/editalbum/{albumId}", method = RequestMethod.GET)
	public ModelAndView editAlbum(@PathVariable("albumId") Long albumId, Page page) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		long userId = 0;
		if (user != null) {
			userId = user.getId();
		} else {
			throw new NotLoginException("登录后才能创建相册");
		}

		Album album = albumService.getAlbumForChange(albumId, userId);

		ModelAndView mav = new ModelAndView(ViewPaths.ALBUM_EDITALBUM);
		mav.addObject("album", album);
		mav.addObject("page", page);

		return mav;
	}

	/**
	 * 修改相册信息
	 * 
	 * @param albumId
	 *            相册Id
	 * @param album
	 * @param page
	 * @param request
	 * */
	@RequestMapping(value = "/editalbum/{albumId}", method = RequestMethod.POST)
	public ModelAndView editAlbum(@PathVariable("albumId") Long albumId, Album album, Page page) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		long userId = 0;
		if (user != null) {
			userId = user.getId();
		} else {
			throw new NotLoginException("登录后才能创建相册");
		}

		String errMsg = validateForm("editAlbumForm", album);
		if (errMsg != null) {
			ModelAndView returnMav = editAlbum(albumId, page);
			return processValidationErrors("errMsg", errMsg, returnMav);
		}

		album.setOwnerId(userId);
		album.setId(albumId);
		albumService.editAlbum(album);
		String url = buildRecirectPath(URL_PREFIX + "/list/" + userId);
		url = url + "?curpage=" + page.getCurpage();

		ModelAndView mav = new ModelAndView(new RedirectView(url));
		return mav;
	}

	@RequestMapping(value = "/newalbum", method = RequestMethod.GET)
	public ModelAndView newAlbum() {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		long userId = 0;
		String userNickname = null;
		String userPortrait = null;
		if (user != null) {
			userId = user.getId();
			userNickname = user.getNickname();
			userPortrait = user.getPortrait();
		} else {
			throw new NotLoginException("登录后才能创建相册");
		}

		ModelAndView mav = new ModelAndView(ViewPaths.ALBUM_NEWALBUM);
		mav.addObject("ownerId", userId);
		mav.addObject("ownerNickname", userNickname);
		mav.addObject("ownerPortrait", userPortrait);

		return mav;
	}

	@RequestMapping(value = "/newalbum", method = RequestMethod.POST)
	public ModelAndView newAlbum(Album album) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("登录后才能创建相册");
		}

		String errMsg = validateForm("newAlbumForm", album);
		if (errMsg != null) {
			ModelAndView returnMav = newAlbum();
			return processValidationErrors("errMsg", errMsg, returnMav);
		}

		Album resultAlbum = albumService.createAlbum(user, album);
		if (resultAlbum == null) {
			LOGGER.warn("数据异常，如果结果为空，应该早已抛出异常！");
			throw new OperateFailedException("创建相册失败");
		}
		String url = buildRecirectPath(URL_PREFIX + "/bupload/" + resultAlbum.getId());
		ModelAndView mav = new ModelAndView(new RedirectView(url));
		return mav;
	}

	/**
	 * 打开上传图片到相册的页面
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@RequestMapping(value = "/upload/{albumId}", method = RequestMethod.GET)
	public ModelAndView toUpload(@PathVariable("albumId") Long albumId) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("上传照片必须登录");
		}
		long userId = user.getId();
		Album album = albumService.getAlbumForChange(albumId, userId);
		ModelAndView mav = new ModelAndView(ViewPaths.ALBUM_TOUPLOAD);
		mav.addObject("album", album);
		// WebHelper.saveToken(request);
		return mav;
	}

	/**
	 * 打开批量上传图片到相册的页面
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@RequestMapping(value = "/bupload/{albumId}", method = RequestMethod.GET)
	public ModelAndView btachUpload(@PathVariable("albumId") Long albumId) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("上传照片必须登录");
		}
		long userId = user.getId();
		Album album = albumService.getAlbumForChange(albumId, userId);
		ModelAndView mav = new ModelAndView(ViewPaths.ALBUM_SWFUPLOAD);
		mav.addObject("album", album);
		// WebHelper.saveToken(request);
		return mav;
	}

	/**
	 * 上传图片到相册
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/upload/{albumId}", method = RequestMethod.POST)
	public ModelAndView normalUpload(@PathVariable("albumId") Long albumId, String submitToken,
			MultipartHttpServletRequest request) {
		User user = (User) WebHelper.getSessionAttribute(request, Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("上传照片必须登录");
		}

		String errMsg = validateForm("normalUploadForm", submitToken);
		if (errMsg != null) {
			ModelAndView returnMav = toUpload(albumId);
			return processValidationErrors("errMsg", errMsg, returnMav);
		}

		long userId = user.getId();
		Album album = albumService.getAlbumForChange(albumId, userId);
		List<MultipartFile> files = request.getFiles("file");
		StringBuilder message = new StringBuilder();
		List<SkylineImageResizeTask> tasks = prepareResizeTask(files, userId, albumId, message);
		if (CollectionUtils.isEmpty(tasks)) {
			ModelAndView mav = new ModelAndView(ViewPaths.ALBUM_TOUPLOAD);
			mav.addObject("message", "没有找到您想传的图片");
			mav.addObject("album", album);
			return mav;
		}

		List<ImageResizeResult> results = imagine.processImage(localStorePath, tasks);
		List<ImageResizeResult> filesInfo = processResizeResult(results, message);

		List<Photo> photos = null;
		if (!CollectionUtils.isEmpty(filesInfo)) {
			photos = albumService.createPhotos(user, album, filesInfo);
		}

		ModelAndView mav = new ModelAndView(ViewPaths.ALBUM_UPLOADOK);
		mav.addObject("album", album);
		mav.addObject("message", message);
		Map<Long, List<Photo>> filesMap = (Map<Long, List<Photo>>) WebHelper.getSessionAttribute(
				request, Constant.SESSION_UPLOAD_OK_FILES);
		if (filesMap == null) {
			filesMap = new HashMap<Long, List<Photo>>();
		}
		filesMap.put(album.getId(), photos);
		WebHelper.setSessionAttribute(request, Constant.SESSION_UPLOAD_OK_FILES, filesMap);

		return mav;
	}

	private List<ImageResizeResult> processResizeResult(List<ImageResizeResult> results,
			StringBuilder message) {
		List<ImageResizeResult> filesInfo = new ArrayList<ImageResizeResult>(results.size());
		for (ImageResizeResult result : results) {
			ResultState state = result.getResultState();
			switch (state) {
			case SUCCESS:
				filesInfo.add(result);
				break;
			case NOT_IMAGE:
				message.append("上传图片" + result.getOriginalFilename() + "失败，失败原因：图片格式不支持。<br/>");
				break;
			default:
				message.append("上传图片" + result.getOriginalFilename() + "失败。<br/>");
				break;
			}
		}
		return filesInfo;
	}

	@SuppressWarnings("rawtypes")
	private List<SkylineImageResizeTask> prepareResizeTask(List files, long userId, long albumId,
			StringBuilder message) {
		if (CollectionUtils.isEmpty(files)) {
			return null;
		}
		boolean isLocal = !(files.get(0) instanceof MultipartFile);
		List<SkylineImageResizeTask> tasks = new ArrayList<SkylineImageResizeTask>(files.size());
		for (Object file : files) {
			long fileSize = 0L;
			String filename = null;
			SkylineImageResizeTask task;

			if (isLocal) {
				File localFile = (File) file;
				fileSize = localFile.length();
				filename = FilenameUtils.getName(localFile.getAbsolutePath());
			} else {
				MultipartFile multipartFile = (MultipartFile) file;
				fileSize = multipartFile.getSize();
				filename = multipartFile.getOriginalFilename();
			}

			if (fileSize == 0) {
				continue;
			}
			if (fileSize > maxSizePerFile) {
				message.append("上传图片" + filename + "失败，失败原因：图片太大。\n");
				continue;
			}

			if (isLocal) {
				File localFile = (File) file;
				task = new LocalImageResizeTask(localFile.getAbsolutePath(), baseSizes);
			} else {
				MultipartFile multipartFile = (MultipartFile) file;
				task = new MultipartImageResizeTask(multipartFile, baseSizes, null, false);
			}

			task.setUserId(userId);
			task.setAlbumId(albumId);

			tasks.add(task);
		}

		return tasks;
	}

	// private List<LocalImageResizeTask> prepareResizeTask(List<File> files,
	// long userId, long albumId, StringBuilder message) {
	// List<MultipartImageResizeTask> tasks = null;
	// if (files != null && !files.isEmpty()) {
	// tasks = new ArrayList<MultipartImageResizeTask>(files.size());
	// for (MultipartFile file : files) {
	// if (file.getSize() == 0) {
	// continue;
	// }
	// if (file.getSize() > maxSizePerFile) {
	// message.append("上传图片" + file.getOriginalFilename() + "失败，失败原因：图片太大。\n");
	// continue;
	// }
	// MultipartImageResizeTask task = new MultipartImageResizeTask(file,
	// baseSizes, null,
	// false);
	// task.setUserId(userId);
	// task.setAlbumId(albumId);
	// tasks.add(task);
	// }
	//
	// }
	// return tasks;
	// }

	/**
	 * 批量上传压缩文件
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/buploadok/{albumId}", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, Object> batchUploadOk(@PathVariable("albumId") Long albumId,
			@RequestParam("files") String files) {
		Map<String, Object> result = new HashMap<String, Object>();
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "压缩图片必须");
			result.put("logined", Boolean.FALSE);
			return result;
		} else {
			result.put("logined", Boolean.TRUE);
		}

		long userId = user.getId();
		String[] filesPath = files.split("\\|");
		List<File> localFiles = new ArrayList<File>(filesPath.length);
		for (String filePath : filesPath) {
			if (!StringUtils.hasLength(filePath)) {
				continue;
			}
			File localFile = new File(filePath);
			localFiles.add(localFile);
		}

		if (localFiles.isEmpty()) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "没有找到需要压缩的文件！");
			return result;
		}

		StringBuilder message = new StringBuilder();
		List<SkylineImageResizeTask> tasks = prepareResizeTask(localFiles, userId, albumId, message);
		if (CollectionUtils.isEmpty(tasks)) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "没有找到需要压缩的文件！");
			return result;
		}

		List<ImageResizeResult> results = imagine.processImage(localStorePath, tasks);
		List<ImageResizeResult> filesInfo = processResizeResult(results, message);

		Album album = null;
		try {
			album = albumService.getAlbumForChange(albumId, userId);
		} catch (Exception e) {
			LOGGER.warn("获取相册失败", e);
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "没有找到对应相册，压缩图片失败！");
			return result;

		}
		List<Photo> photos = null;
		if (!CollectionUtils.isEmpty(filesInfo)) {
			photos = albumService.createPhotos(user, album, filesInfo);
		}

		Map<Long, List<Photo>> filesMap = (Map<Long, List<Photo>>) WebHelper.getSessionAttribute(
				null, Constant.SESSION_UPLOAD_OK_FILES);
		if (filesMap == null) {
			filesMap = new HashMap<Long, List<Photo>>();
		}
		filesMap.put(album.getId(), photos);
		WebHelper.setSessionAttribute(null, Constant.SESSION_UPLOAD_OK_FILES, filesMap);

		if (StringUtils.hasLength(message)) {// 存在错误
			result.put("success", Boolean.FALSE);
			result.put("errmsg", message);
		} else {
			result.put("success", Boolean.TRUE);
			result.put("errmsg", "压缩图片成功！");
		}

		return result;
	}

	/**
	 * 修改图片信息
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@RequestMapping(value = "/uploadok/{albumId}", method = RequestMethod.GET)
	public ModelAndView uploadOk(@PathVariable("albumId") Long albumId) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("上传照片必须登录");
		}
		long userId = user.getId();
		Album album = albumService.getAlbumForChange(albumId, userId);

		ModelAndView mav = new ModelAndView(ViewPaths.ALBUM_UPLOADOK);
		mav.addObject("album", album);

		return mav;
	}

	/**
	 * 修改图片信息
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@RequestMapping(value = "/uploadok/{albumId}", method = RequestMethod.POST)
	public ModelAndView uploadOk(@PathVariable("albumId") Long albumId, String cover, String ext,
			@RequestParam("description") List<String> descriptions,
			@RequestParam("id") List<Long> ids, String submitToken) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("上传照片必须登录");
		}

		ModelAndView returnMav = null;
		String errMsg = validateForm("uploadOkForm", submitToken);
		if (errMsg != null) {
			returnMav = uploadOk(albumId);
			return processValidationErrors("errMsg", errMsg, returnMav);
		}

		int size = Math.min(ids.size(), descriptions.size());
		StringBuilder errMsgBuilder = new StringBuilder();
		for (int i = 0; i < size; i++) {
			if (ids.get(i) == null) {
				LOGGER.warn("上传后修改图片信息操作失败，ID为:" + albumId + "的相册提交的第" + i + "张图片的ID为空");
				continue;
			}
			errMsg = validateForm("descriptionOnlyForm", descriptions.get(i));
			if (errMsg != null) {
				if (returnMav == null) {
					returnMav = uploadOk(albumId);
				}
				errMsgBuilder.append("第").append(i + 1).append("张图片的").append(errMsg);
				return processValidationErrors("errMsg", errMsgBuilder.toString(), returnMav);
			}
		}

		albumService.changePhotosDescription(albumId, ids, descriptions);
		albumService.changeAlbumCover(user.getId(), albumId, cover, ext);

		WebHelper.removeSessionAttribute(null, Constant.SESSION_UPLOAD_OK_FILES);
		String url = buildRecirectPath(URL_PREFIX + "/view/" + albumId);

		ModelAndView mav = new ModelAndView(new RedirectView(url));
		return mav;
	}

	@RequestMapping(value = "/delphoto/{photoId}", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView deletePhoto(@PathVariable("photoId") long photoId) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		long userId = 0;
		if (user != null) {
			userId = user.getId();
		}

		Long albumId = albumService.deletePhoto(userId, photoId);
		String url = buildRecirectPath(URL_PREFIX + "/view/" + albumId);

		ModelAndView mav = new ModelAndView(new RedirectView(url));
		return mav;
	}

	@RequestMapping(value = "/editphoto/{photoId}", method = RequestMethod.GET)
	public ModelAndView editPhoto(@PathVariable("photoId") long photoId) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("编辑照片信息必须登录");
		}
		long userId = user.getId();

		List<Album> albums = albumService.listAlbumNamesOfUser(userId);
		Photo photo = albumService.getPhotoForChange(userId, photoId);

		ModelAndView mav = new ModelAndView(ViewPaths.ALBUM_EDITPHOTO);
		mav.addObject("photo", photo);
		mav.addObject("albums", albums);

		Long curAlbumId = photo.getAlbumId();
		for (Album album : albums) {
			if (album.getId().equals(curAlbumId)) {
				mav.addObject("cover", album.getCover());
			}
		}

		return mav;
	}

	@RequestMapping(value = "/editphoto/{photoId}", method = RequestMethod.POST)
	public ModelAndView editPhoto(@PathVariable("photoId") long photoId, String setCover,
			String toAlbumId, @RequestParam("description") String description, String submitToken) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("编辑照片信息必须登录");
		}

		Long toAlbum = NumberUtils.toLong(toAlbumId);

		Map<String, String> formData = new HashMap<String, String>();
		formData.put("submitToken", submitToken);
		formData.put("description", description);
		String errMsg = validateForm("editPhotoForm", formData);
		if (errMsg != null) {
			ModelAndView returnMav = editPhoto(photoId);
			return processValidationErrors("errMsg", errMsg, returnMav);
		}

		long userId = user.getId();
		Photo photo = albumService.getPhotoForChange(userId, photoId);
		Album origAlbum = albumService.getAlbumForChange(photo.getAlbumId(), userId);
		if (setCover == null) {
			if (!photo.getAlbumId().equals(toAlbum)) {
				albumService.changePhotoAlbum(userId, photoId, photo.getAlbumId(), toAlbum);
				if (origAlbum.getCover().equals(photo.getSmallFile())) {// 取消原有封面
					albumService.changeAlbumCover(userId, photo.getAlbumId(), cover, ext);
				}
			}
		} else {
			albumService.changeAlbumCover(userId, photo.getAlbumId(), photo.getSmallFile(),
					photo.getExt());
		}
		String oldDesc = CommonUtils.nullStringToEmpty(photo.getDescription());
		if (!oldDesc.equals(description)) {
			albumService.changePhotoDescription(photo.getAlbumId(), photoId, description);
		}

		String url = buildRecirectPath(URL_PREFIX + "/photo/" + photoId);
		ModelAndView mav = new ModelAndView(new RedirectView(url));
		return mav;
	}

	@RequestMapping(value = "/changephotodesc/{photoId}", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, Object> changePhotoDescription(@PathVariable("photoId") long photoId,
			@RequestParam("description") String description) {
		Map<String, Object> result = new HashMap<String, Object>();
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "修改照片描述必须登录");
			result.put("logined", Boolean.FALSE);
			return result;
		}
		result.put("logined", Boolean.TRUE);

		Errors errors = ValidationUtils.validateForm("descriptionOnlyForm", description);
		String[] errorMsgs = ValidationUtils.getAllErrorMessages(errors);
		if (errorMsgs.length > 0) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", errorMsgs[0]);
			return result;
		}

		try {
			Photo photo = albumService.getPhotoForChange(user.getId(), photoId);
			String oldDesc = CommonUtils.nullStringToEmpty(photo.getDescription());
			if (!oldDesc.equals(description)) {
				albumService.changePhotoDescription(photo.getAlbumId(), photoId, description);
			}
			result.put("success", Boolean.TRUE);
			result.put("errmsg", "修改照片描述成功");
			return result;
		} catch (Exception e) {
			LOGGER.error("修改照片描述失败", e);
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "修改照片描述失败");
			return result;
		}

	}

	@RequestMapping(value = "/setcover/{photoId}", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, Object> changePhotoCover(@PathVariable("photoId") long photoId) {
		Map<String, Object> result = new HashMap<String, Object>();
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "设置相册封面必须登录");
			result.put("logined", Boolean.FALSE);
			return result;
		}
		result.put("logined", Boolean.TRUE);

		try {
			Photo photo = albumService.getPhotoForChange(user.getId(), photoId);
			albumService.changeAlbumCover(user.getId(), photo.getAlbumId(), photo.getSmallFile(),
					photo.getExt());
			result.put("success", Boolean.TRUE);
			result.put("errmsg", "设置相册封面成功");
			return result;
		} catch (Exception e) {
			LOGGER.error("设置相册封面失败", e);
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "设置相册封面失败");
			return result;
		}

	}

	@RequestMapping(value = "/viewphoto/{photoId}", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, Object> viewPhoto(@PathVariable("photoId") long photoId) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
			long viewerId = 0;
			boolean addVisitCount = false;
			if (user != null) {
				viewerId = user.getId();
				// FIXME 判断是否需要增加访问量
			}
			int authority = AuthorityUtil.getAuthority(null, viewerId);
			Photo photo = albumService.getPhotoDetailById(photoId, viewerId, addVisitCount);
			// 判断权限
			if (photo != null) {
				int albumAuth = photo.getAuthority();
				if (authority < albumAuth) {
					LOGGER.warn("用户ID" + viewerId + "没有访问ID为" + photo.getId() + "图片的权限");
					result.put("success", Boolean.FALSE);
					result.put("errmsg", "您没有查看该图片的权限");
					return result;
				}
			}
			result.put("success", Boolean.TRUE);
			result.put("errmsg", "获取图片成功");
			result.put("photo", photo);
			return result;
		} catch (Exception e) {
			LOGGER.error("", e);
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "系统发生异常，请稍候再试...");
			return result;
		}
	}

	@RequestMapping(value = "/setportrait/{photoId}", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, Object> changeAsUserPortrait(@PathVariable("photoId") long photoId) {
		Map<String, Object> result = new HashMap<String, Object>();
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "设置头像必须登录");
			result.put("logined", Boolean.FALSE);
			return result;
		}
		result.put("logined", Boolean.TRUE);

		try {
			Long ownerId = user.getId();
			Photo photo = albumService.getPhotoForChange(ownerId, photoId);
			Album portraitAlbum = albumService.getUserPortraitAlbum(ownerId);
			Long albumId = portraitAlbum.getId();
			String photoExt = photo.getExt();
			String remoteFileKey = photo.getSmallFile() + '.' + photoExt;
			if (SkylineImagineUtils.isExtMultiFrame(photoExt)) {// 如果是动态图，需要压缩成单帧图
				remoteFileKey = photo.getMiddleFile() + '.' + photoExt;
				String filename = FilenameUtils.getName(remoteFileKey);
				String fileKey = SkylineImagineUtils.generateFileKey(ownerId.toString(),
						albumId.toString(), filename);
				String localFile = SkylineImagineUtils.generateFilePath(localStorePath, ownerId,
						albumId, fileKey + '.' + photoExt);
				File destFile = new File(localFile);

				File dir = destFile.getParentFile();
				if (!dir.exists()) {
					boolean success = dir.mkdirs();
					if (!success && !dir.exists()) {
						LOGGER.warn("mkdirs :" + dir + " failed");
					}
				}
				// 保存服务器上的图片到本地目标文件
				if (fileOperator == null) {
					String srcFile = localStorePath + '/' + remoteFileKey;
					FileUtils.copyFile(new File(srcFile), destFile);
				} else {
					fileOperator.downloadFile(remoteFileKey, localFile);
				}
				// 压缩该目标图片
				LocalImageResizeTask task = new LocalImageResizeTask(localFile, baseSizes);
				task.setAlbumId(albumId);
				task.setUserId(ownerId);
				task.setSupportMulitFrame(false);
				ImageResizeResult resizeResult = imagine.processSingleImage(localStorePath, task);
				Photo portrait = albumService
						.createPortraitPhoto(user, portraitAlbum, resizeResult);
				remoteFileKey = portrait.getSmallFile() + '.' + portrait.getExt();
			} else {
				albumService.copyPhotoToPortraitAlbum(portraitAlbum, photo);
			}

			SkylineImageCropTask cropTask = new SkylineImageCropTask(remoteFileKey, portraitSize);
			cropTask.setAlbumId(albumId);
			cropTask.setUserId(ownerId);
			ImageCropResult cropResult = crop.processImage(localStorePath, cropTask);
			String portraitFile = cropResult.getFileKey();

			personalInfoService.changeUserPortrait(ownerId, portraitFile);
			user.setPortrait(portraitFile);
			WebHelper.setSessionAttribute(null, Constant.SESSION_USER, user);

			result.put("success", Boolean.TRUE);
			result.put("errmsg", "设置头像成功");
			return result;
		} catch (Exception e) {
			LOGGER.error("设置相册封面失败", e);
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "设置头像失败");
			return result;
		}

	}

	/** -------------------华丽的分割线，下面的还没实现呢-------------------------------- **/

	// @RequestMapping(value = "/reorder/{albumid}", method = RequestMethod.GET)
	// public ModelAndView toReorderAlbum(@PathVariable("albumid") long albumId)
	// {
	// User user = (User) WebHelper.getSessionAttribute(null,
	// Constant.SESSION_USER);
	// long viewerId = 0;
	// if (user != null) {
	// viewerId = user.getId();
	// }
	//
	// List<Photo> photos = albumService.listPhotosOfAlbumForChange(albumId,
	// viewerId);
	// ModelAndView mav = new ModelAndView(reorderAlbumView);
	// mav.addObject("photos", photos);
	// return mav;
	// }
	//
	// @RequestMapping(value = "/reorder", method = RequestMethod.POST)
	// public ModelAndView reorderAlbum(@RequestParam("albumid") long albumId,
	// @RequestParam("photoid") List<Long> photoIds)
	// {
	// User user = (User) WebHelper.getSessionAttribute(null,
	// Constant.SESSION_USER);
	// long viewerId = 0;
	// if (user != null) {
	// viewerId = user.getId();
	// }
	//
	// List<Photo> photos = albumService.listPhotosOfAlbumForChange(albumId,
	// viewerId);
	// ModelAndView mav = new ModelAndView(reorderAlbumView);
	// mav.addObject("photos", photos);
	// return mav;
	// }

	// @RequestMapping(value = "/ajaxview/{userId}", method = RequestMethod.GET)
	// public @ResponseBody
	// Map<String, Object> ajaxViewAlbum(@PathVariable("userId") long ownerId,
	// Page page) {
	// User user = (User) WebHelper.getSessionAttribute(null,
	// Constant.SESSION_USER);
	// long viewerId = user.getId();
	//
	// page.setSize(20);
	// int authority = 0;
	// List<Album> albums =
	// albumService.listAlbumsOfUserWithoutPortrait(ownerId, viewerId,
	// authority, page);
	// Map<String, Object> map = new HashMap<String, Object>();
	// map.put("albums", albums);
	// if (albums != null && !albums.isEmpty()) {
	// map.put("ownerId", albums.get(0).getOwnerId());
	// }
	// return map;
	// }

	// @RequestMapping(value = "/modifyphtinfo/{photoId}", method =
	// RequestMethod.GET)
	// public ModelAndView changePhotoInfo(@PathVariable("photoId") long
	// photoId) {
	// ModelAndView mav = new ModelAndView(modifyPhotoInfoView);
	// return mav;
	// }
	//
	// @RequestMapping(value = "/modifyphtinfo", method = RequestMethod.POST)
	// public String changePhotoInfo(@RequestParam("photoid") long photoId,
	// @RequestParam("photoname") String photoName,
	// @RequestParam("iscover") int isCover) {
	// return "redirect:";
	// }

}
